#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
	int x=0;bool f=0;char ch=getchar();
	while(ch<'0'||ch>'9')f^=(ch=='-'),ch=getchar();
	while('0'<=ch&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}
const int Maxn=1e6+5,mod=998244353;
int n,m;
int a[Maxn];
struct tree{
	int root;
	int f[Maxn][21];
	int head[Maxn],to[Maxn],nxt[Maxn],cnt1;
	inline void add(int u,int v){
		to[++cnt1]=v;
		nxt[cnt1]=head[u];
		head[u]=cnt1;
	}
	int dep[Maxn],si[Maxn];
	void dfs(int u){
		dep[u]=dep[f[u][0]]+1;
		for(int i=1;i<=12;i++)f[u][i]=f[f[u][i-1]][i-1];
		si[u]=1;
		for(int i=head[u];i;i=nxt[i]){
			int y=to[i];
			dfs(y);
			si[u]+=si[y];
		}
	}
	inline int lca(int u,int v){
		if(u==v)return u;
		if(dep[u]<dep[v])swap(u,v);
		for(int i=12;~i;i--)
			if(dep[f[u][i]]>=dep[v])u=f[u][i];
		if(u==v)return u;
		for(int i=12;~i;i--)
			if(f[u][i]&&f[v][i]&&f[u][i]!=f[v][i])u=f[u][i],v=f[v][i];
		return f[u][0];
	}
	inline int get(int u,int v){
		for(int i=12;~i;i--)
			if(f[u][i]&&dep[f[u][i]]>v)u=f[u][i];
		return u;
	}
}A,B;
namespace sub1{
	int g[1005][1005];
	int ans=0;
	inline void cost(int u,int v){
		if(A.dep[u]<A.dep[v])swap(u,v);
		if(A.lca(u,v)==v)ans=(ans+g[a[u]][a[v]]*A.si[u]%mod*(n-A.si[A.get(u,v)])%mod)%mod;
		else{
			ans=(ans+g[a[u]][a[v]]*A.si[u]%mod*A.si[v]%mod)%mod;
		}
	}
	inline void solve(){
		A.dfs(A.root);
		B.dfs(B.root);
		for(int i=1;i<=m;i++)
			for(int j=i;j<=m;j++)
				g[i][j]=g[j][i]=B.dep[B.lca(i,j)];
		for(int u=1;u<=n;u++){
			for(int v=u+1;v<=n;v++){
				cost(u,v);
			}
		}printf("%lld\n",ans);
	}
}
signed main(){
	freopen("tree.in","r",stdin);
	freopen("tree.out","w",stdout);
	n=read();m=read();
	for(int i=1;i<=n;i++){
		A.f[i][0]=read();
		if(A.f[i][0]==0)A.root=i;
		else A.add(A.f[i][0],i);
	}
	for(int i=1;i<=m;i++){
		B.f[i][0]=read();
		if(B.f[i][0]==0)B.root=i;
		else B.add(B.f[i][0],i);
	}
	for(int i=1;i<=n;i++)a[i]=read();
	if(max(n,m)<=1000)sub1::solve(),exit(0);
	return 0;
}

